﻿using System;
using System.Threading;
using NsbExtensions.Utilities;

namespace NsbExtensions.Tests.Stubs
{
    internal delegate object WorkDelegate();

    public class BusyBackgroundService : BackgroundServiceBase
    {
        public Exception Error;
        public long PendingWorkCount;
        public long WorkCompleteCount;

        public ManualResetEvent WorkQueue = new ManualResetEvent(false);


        protected override void ShutDownService()
        {
        }

        protected override void StartService()
        {
        }

        public void DoWork(int howMuchWork)
        {
            for (int i = 0; i < howMuchWork; i++)
            {
                WorkDelegate del = Work;
                del.BeginInvoke(WorkDone, del);
            }
        }

        private void WorkDone(IAsyncResult ar)
        {
            var del = ar.AsyncState as WorkDelegate;
            if (del != null)
            {
                object result = del.EndInvoke(ar);

                Error = result as Exception;
            }
        }

        private object Work()
        {
            try
            {
                using (new BusyHandle(this))
                {
                    Interlocked.Increment(ref PendingWorkCount);
                    WorkQueue.WaitOne();
                    Thread.Sleep(100);
                    Interlocked.Increment(ref WorkCompleteCount);
                    Interlocked.Decrement(ref PendingWorkCount);
                }
            }
            catch (Exception ex)
            {
                return ex;
            }
            return null;
        }
    }
}